package pri.zxx.webdemo.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import pri.zxx.webdemo.interceptor.HttpClientInterceptor;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * one request time spent = 10 ms(calculate) + 190ms(io wait) => 8 core: 20 * 8 = 160(max) => 2^3 << 4
 *
 * @author shich
 * @since 2020/5/8 21:06
 */
@Slf4j
@Configuration
public class ThreadConfiguration {
    private static final String PREFIX = "WOW-THREAD-POOL-";
    private static final AtomicInteger COUNTER = new AtomicInteger();
    private static final Integer CPU_CORE_SIZE = Runtime.getRuntime().availableProcessors();
    private static final int CORE_POOL_SIZE = CPU_CORE_SIZE << 4;
    private static final int MAXIMUM_POOL_SIZE = CPU_CORE_SIZE << 6;
    private static final long KEEP_ALIVE_TIME = 1;
    private static final TimeUnit UNIT = TimeUnit.MINUTES;
    private static final BlockingQueue<Runnable> WORK_QUEUE = new ArrayBlockingQueue<>(CPU_CORE_SIZE << 6);
    private static final ThreadFactory THREAD_FACTORY = r -> new Thread(r, PREFIX + COUNTER.getAndIncrement());
    private static final RejectedExecutionHandler HANDLER = (r, e) -> log.warn(PREFIX + "线程池：丢弃任务！请检查相关引用是否合理，或适当调整线程池配置！");

    @Bean
    public ThreadPoolExecutor threadPoolExecutor() {
        return new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_TIME, UNIT, WORK_QUEUE, THREAD_FACTORY, HANDLER);
    }

    @Bean
    public HandlerInterceptor handlerInterceptor(){
        return new HttpClientInterceptor();
    }
}
